package ccxz.biz.application.service;

import ccxz.biz.application.dto.ExcelImportVO;
import ccxz.biz.application.dto.ImageDTO;
import ccxz.biz.application.dto.SymptomDTO;
import ccxz.biz.application.util.*;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class BizApplicationService {

    @Value("${config.doctor}")
    private String doctor;

    @Value("${config.audit}")
    private String audit;

    private List<String> handlePrescription(SymptomDTO symptomDTO) {
        List<String> keywords = new ArrayList<>();
        List<String> result = new ArrayList<>(symptomDTO.getResult());
        Collections.shuffle(result);

        int total = result.size();
        int pageSize = 4;
        int pageSum = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;

        for (int pageNo = 1; pageNo <= pageSum; pageNo++) {
            List<String> subList = result.stream().skip((long) (pageNo - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
            keywords.add(String.join("  ", subList));
        }
        return keywords;
    }


    private String handleSexBySymptom(String symptom) {
        if (!StringUtils.hasText(symptom)) {
            return "";
        }
        if (symptom.contains("男")) {
            return "男";
        } else if (symptom.contains("女")) {
            return "女";
        }

        List<String> female = SexUtil.getFemale();
        for (String x : female) {
            if (symptom.contains(x)) {
                return "女";
            }
        }

        List<String> male = SexUtil.getMale();
        for (String x : male) {
            if (symptom.contains(x)) {
                return "男";
            }
        }
        return "";
    }


    /**
     * 文件夹逻辑是这样
     * 文件夹划分一共分为5个
     * 权重依次是  《特殊  男科   妇科   安神  健脾 》
     * 先判定一下   如果剂量不是   15天/30包/早晚各一包的话  保存到特殊文件夹   是的话依次判断
     * 如果匹配到男科中的症状  则保存到男科文件夹   没有的话匹配到妇科保存到妇科文件夹   还没有的话匹配到安神中的关键词保存到安神文件夹    剩余保存到脾胃文件夹
     */

    private SymptomDTO handlePrescriptionBySymptom(String symptom) {
        SymptomDTO symptomDTO = new SymptomDTO(new ArrayList<>(), null);
        Collection<String> cacheResult = new HashSet<>();
        int standRange = RandomUtil.max();
        boolean nan = SymptomUtil.nanKe(cacheResult, symptom);
        if (nan) { // 男科
            symptomDTO.setFileDir("男科");
            this.handelSymptomResult(cacheResult, standRange, symptomDTO);
            return symptomDTO;
        }

        boolean fu = SymptomUtil.fuKe(cacheResult, symptom);
        if (fu) {
            symptomDTO.setFileDir("妇科");
            this.handelSymptomResult(cacheResult, standRange, symptomDTO);
            return symptomDTO;
        }

        boolean anShen = SymptomUtil.anShen(cacheResult, symptom);
        if (anShen) {
            symptomDTO.setFileDir("安神");
            this.handelSymptomResult(cacheResult, standRange, symptomDTO);
            return symptomDTO;
        }

        boolean piWei = SymptomUtil.piWei(cacheResult, symptom);
        if (piWei) {
            symptomDTO.setFileDir("脾胃");
            this.handelSymptomResult(cacheResult, standRange, symptomDTO);
            return symptomDTO;
        }

        List<String> randomSome = SymptomUtil.randomSome(standRange);
        this.handelSymptomResult(randomSome, standRange, symptomDTO);
        return symptomDTO;
    }

    private void handelSymptomResult(Collection<String> cacheResult, int standRange, SymptomDTO symptomDTO) {
        List<String> cacheList = new ArrayList<>();
        cacheList.addAll(cacheResult);
        Collections.shuffle(cacheList);
        List<String> result = cacheList.subList(0, standRange);
        result.forEach(x -> symptomDTO.getResult().add(x.replace("s", WeightRandomStrategyUtil.getNum())));
    }

    public void handle(ExcelImportVO request, String path) throws Exception {
        if (!StringUtils.hasText(request.getOrderId())) {
            return;
        }
        if (!StringUtils.hasText(request.getDosage())) {
            return;
        }

        File desktopPath = new File(System.getProperty("user.home") + "/Desktop");
        System.out.println(JSON.toJSONString(request));
//        try (
//                InputStream tis = new ClassPathResource("inquiry_result_template.png").getInputStream();
//                InputStream fis = new ClassPathResource("guoxiang.ttf").getInputStream();
//                InputStream f2is = new ClassPathResource("huaxi.ttf").getInputStream()) {
        try {
            InputStream tis = Files.newInputStream(new File(desktopPath.getAbsolutePath() + "/guzhentang/inquiry_result_template.png").toPath());
            InputStream fis = Files.newInputStream(new File(desktopPath.getAbsolutePath() + "/guzhentang/中国式手写风.ttf").toPath());
            InputStream f2is = Files.newInputStream(new File(desktopPath.getAbsolutePath() + "/guzhentang/huaxi.ttf").toPath());

            String[] split = request.getOrderId().split("-");
            request.setCreateTime(DateUtil.dateTrans(split[0]));
            if (request.getName().contains("[")) {
                request.setName(request.getName().substring(0, request.getName().indexOf('[')));
            }
            request.setName(request.getName().replaceAll("\\*", ""));
            request.setSex(this.handleSexBySymptom(request.getRawSymptom()));
            request.setSymptom(request.getSymptom() + split[1] + "-" + request.getSerialNumber());

//            List<String> keywords = this.handlePrescription(request.getKeywords());
            SymptomDTO symptomDTO = this.handlePrescriptionBySymptom(request.getRawSymptom());
            List<String> keywords = this.handlePrescription(symptomDTO);
            if (symptomDTO.getFileDir() == null) {
                symptomDTO.setFileDir("其他");
            }

            String s = request.getDosage().replaceAll("/", "");
            symptomDTO.setFileDir("_" + s + "/" + symptomDTO.getFileDir());

            Color color = new Color(0, 0, 0);

            Font dynamicFont = Font.createFont(Font.TRUETYPE_FONT, fis);
            Font guoxiangFont = dynamicFont.deriveFont(Font.PLAIN, 100); // ttf字体加载方式

            Font dynamicFont2 = Font.createFont(Font.TRUETYPE_FONT, f2is);
            Font huaxiFont = dynamicFont2.deriveFont(Font.PLAIN, 88); // ttf字体加载方式


            Font fangsongFont = new Font("仿宋", Font.PLAIN, 66);

            ArrayList<ImageDTO> list = new ArrayList<>();

            list.add(createImageDTO(doctor, color, huaxiFont, 420, 3300));
            list.add(createImageDTO(audit, color, guoxiangFont, 920, 3300));
            list.add(createImageDTO(request.getPharmacy(), color, huaxiFont, 1990, 3300));


            list.add(createImageDTO(request.getName(), color, fangsongFont, 410, 525));
            list.add(createImageDTO(request.getSex(), color, fangsongFont, 1022, 525));
            list.add(createImageDTO(request.getAge(), color, fangsongFont, 1733, 525));
            list.add(createImageDTO(request.getDepartment(), color, fangsongFont, 410, 670));
            list.add(createImageDTO(request.getFeeType(), color, fangsongFont, 1022, 670));
            list.add(createImageDTO(request.getCreateTime(), color, fangsongFont, 1733, 670));


            list.add(createImageDTO(request.getSymptom(), color, fangsongFont, 333, 831, true));  // 换行
//            list.add(createImageDTO(request.getPrescription(), color, fangsongFont, 333, 1650, true)); // 换行

            int colHeight = 1670;
            for (String row : keywords) {
                list.add(createImageDTO(row, color, fangsongFont, 333, colHeight));
                colHeight = colHeight + 120;
            }

            list.add(createImageDTO(request.getDrugType(), color, fangsongFont, 450, 3060));
            list.add(createImageDTO(request.getDosage(), color, fangsongFont, 1081, 3060));
            list.add(createImageDTO(request.getProcessingFee(), color, fangsongFont, 1466, 3288));


            Image srcImg = ImageIO.read(tis);//文件转化为图片
            int srcImgWidth = srcImg.getWidth(null);//获取图片的宽
            int srcImgHeight = srcImg.getHeight(null);//获取图片的高

            //添加文字:
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            for (ImageDTO imgDTO : list) {
                g.setColor(imgDTO.getColor());                                  //根据图片的背景设置水印颜色
                g.setFont(imgDTO.getFont());                                    //设置字体
                if (imgDTO.isAutoBr()) {
                    GraphicsUtil.drawWrapString(g, imgDTO.getText(), imgDTO.getX(), imgDTO.getY(), 1888, 100);
                } else {
                    g.drawString(imgDTO.getText(), imgDTO.getX(), imgDTO.getY());   //画出水印
                }
            }
            g.dispose();

            String visitPath = desktopPath.getAbsolutePath() + path + "/" + symptomDTO.getFileDir() + "/";
            String filename = visitPath + System.currentTimeMillis() + "_" + request.getName() + ".png";
            File parentFile = new File(filename).getParentFile();
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            // 输出图片
            FileOutputStream outImgStream = new FileOutputStream(filename);
            ImageIO.write(bufImg, "png", outImgStream);
            bufImg.flush();
            outImgStream.flush();
            outImgStream.close();
        } catch (Exception e) {
            log.error("保存问诊书异常", e);
            throw e;
        }
    }

    /**
     * 创建ImageDTO, 每一个对象,代表在该图片中要插入的一段文字内容:
     *
     * @param text  : 文本内容;
     * @param color : 字体颜色(前三位)和透明度(第4位,值越小,越透明);
     * @param font  : 字体的样式和字体大小;
     * @param x     : 当前字体在该图片位置的横坐标;
     * @param y     : 当前字体在该图片位置的纵坐标;
     * @return
     */
    private static ImageDTO createImageDTO(String text, Color color, Font font, int x, int y) {
        ImageDTO imageDTO = new ImageDTO();
        imageDTO.setText(text);
        imageDTO.setColor(color);
        imageDTO.setFont(font);
        imageDTO.setX(x);
        imageDTO.setY(y);
        return imageDTO;
    }

    /**
     * 创建ImageDTO, 每一个对象,代表在该图片中要插入的一段文字内容:
     *
     * @param text  : 文本内容;
     * @param color : 字体颜色(前三位)和透明度(第4位,值越小,越透明);
     * @param font  : 字体的样式和字体大小;
     * @param x     : 当前字体在该图片位置的横坐标;
     * @param y     : 当前字体在该图片位置的纵坐标;
     * @return
     */
    private static ImageDTO createImageDTO(String text, Color color, Font font, int x, int y, boolean autoBr) {
        ImageDTO imageDTO = new ImageDTO();
        imageDTO.setText(text);
        imageDTO.setColor(color);
        imageDTO.setFont(font);
        imageDTO.setX(x);
        imageDTO.setY(y);
        imageDTO.setAutoBr(autoBr);
        return imageDTO;
    }
}
